Visaの新サービス(Visa Developer)のサンプルコードをSwiftに変換してみた。
1 はじめに
本日お昼に、「Visaの新サービス(Visa Developer)のサンプルコードをObjective−Cに変換してみた。」というタイトルでブログを書いたのですが、某所から「Swiftも」という声を頂いたので書きました。
Visa Developerのサービスの詳しい情報はは、先のページをご参照ください。
2 Swift版
Objective-C版を、そのままSwiftのプロジェクトにコピーして、エラーが無くなるまで変換しました。 あまり、Swiftらしい書き方には拘らず、あくまで、本家のサンプルに近い形になっています。
当然というば当然ですが、他の言語から移植するのとは、作業量が圧倒的に違います。
@IBAction func tapButton(sender: AnyObject) { let baseUri = "cybersource/" let resourcePath = "payments/v1/authorizations" let url = "https://sandbox.api.visa.com/\(baseUri)\(resourcePath)?apikey=\(API_KEY)" let body = "{\"amount\": \"0\", \"currency\": \"USD\", \"payment\": { \"cardNumber\": \"4111111111111111\", \"cardExpirationMonth\": \"10\", \"cardExpirationYear\": \"2016\" }}" let xPayToken = getXPayToken(resourcePath, queryString: "apikey=\(API_KEY)", requestBody: body) as String let request = NSMutableURLRequest(URL: NSURL(string: url)!) request.HTTPMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue(xPayToken, forHTTPHeaderField: "x-pay-token") let postBody = NSMutableData() postBody.appendData(body.dataUsingEncoding(NSUTF8StringEncoding)!) request.HTTPBody = postBody let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(request) { ( let data, let response, let error) in guard let _:NSData = data, let _:NSURLResponse = response where error == nil else { print("Error") return } let responseString:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)! print(responseString) dispatch_async( dispatch_get_main_queue(), { self.textView.text = responseString as String } ); } task.resume() } func getXPayToken(apiNameURI:NSString, queryString:NSString, requestBody:NSString) -> NSString { let timestamp = getTimestamp() let sourceString = "\(SHARED_SECRET)\(timestamp)\(apiNameURI)\(queryString)\(requestBody)" let hash = getDigest(sourceString) return "x:\(timestamp):\(hash)" } func getTimestamp() -> NSString { let date = NSDate().timeIntervalSince1970 return NSString(format: "%.0f", date) } func getDigest(date:NSString) -> NSString { if let d = date.dataUsingEncoding(NSASCIIStringEncoding) { var bytes = [UInt8](count: 64, repeatedValue: 0) CC_SHA256(d.bytes, CC_LONG(d.length), &bytes) let digest = NSMutableString(capacity: 64) for var i=0; i<32; i++ { digest.appendFormat("%02x", bytes[i]) } return digest } return "" }
Objective-Cと比較して、行数は同じぐらいですが、やっぱり文字数はかなり少ない感じ・・・
3 最後に
実は、今回も認証エラー(401)で、少し悩みました。
結果的には、変換中に変数を1個消してしまっていただけなので、慎重にやってれば、嵌らなかった筈です。
しかし、このように、サーバ側から詳しいエラーの原因を得られない場合は、作業に一定の時間がかかることを見積もる必要があるかも知れません。
もう少しで、飛行機出発します。 それまでに、Submitできてよかったです。